package fr.auzaiphe.admin.model;

import java.util.ArrayList;

import fr.auzaiphe.admin.constantes.ConstantesAdmin;
import fr.auzaiphe.joueur.model.JoueurModel;

/**
 * @author Hugp
 * Classe de gestion du chrono general, pointant sur les indices a activer (en plus des alertes).
 */
public class ChronoGeneral extends ChronoAdmin
{
	private ArrayList<FlagIndice> flagIndicesDebut;
	private ArrayList<FlagIndice> flagIndicesFin;

	/**
	 * Constructeur par défaut
	 */
	public ChronoGeneral(AdminModel pModel)
	{
		super(pModel);
		this.flagIndicesDebut = new ArrayList<FlagIndice>();
		this.flagIndicesFin = new ArrayList<FlagIndice>();
	}

	/**
	 * Constructeur
	 * @param pTempsRestant Temps initial du chrono
	 */
	public ChronoGeneral(int pTempsRestant, AdminModel pModel)
	{
		super(pTempsRestant, pModel);
		this.flagIndicesDebut = new ArrayList<FlagIndice>();
		this.flagIndicesFin = new ArrayList<FlagIndice>();
	}

	public ChronoGeneral(JoueurModel joueurModel)
	{
		super(joueurModel);
	}

	/**
	 * Méthode décrémentant le chrono
	 */
	@Override
	public void run()
	{
		while( this.run && this.tempsRestant > 0 )
		{
			try
			{
				Thread.sleep(1000);
				this.tempsRestant--;
				((AdminModel) this.model).updateVue();
				this.checkSendAlerte();
				this.checkIndice();
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}

		if ( this.tempsRestant == 0 )
		{
			this.interrupt();
		}
	}

	/**
	 * addFlagIndicesDebut : Ajoute un indice et sa date d'activation dans la liste flagIndicesDebut du chrono.
	 * @param pIndice Indice à cibler
	 * @param pHeure Heure d'activation de l'indice
	 * @return
	 * 		- false si un même indice à activer à la même heure était dans la liste de flagIndicesDebut
	 * 		- true si l'indice a été ajouté et était nouveau.
	 */
	public boolean addFlagIndicesDebut(Indice pIndice, int pHeure)
	{
		FlagIndice flagIndiceTmp = new FlagIndice(pIndice,pHeure);
		if(!this.flagIndicesDebut.contains(flagIndiceTmp))
		{
			this.flagIndicesDebut.add(flagIndiceTmp);
			return true;
		}
		return false;
	}

	/**
	 * addFlagIndicesFin : Ajoute un indice et sa date de désactivation dans la liste flagIndicesFin du chrono.
	 * @param pIndice Indice à cibler
	 * @param pHeure Heure d'ae desactivation de l'indice
	 * @return
	 * 		- false si un même indice à désactiver à la même heure était dans la liste de flagIndicesFin
	 * 		- true si l'indice a été ajouté et était nouveau.
	 */
	public boolean addFlagIndicesFin(Indice pIndice, int pHeure)
	{
		FlagIndice flagIndiceTmp = new FlagIndice(pIndice,pHeure);
		if(!this.flagIndicesFin.contains(flagIndiceTmp))
		{
			this.flagIndicesFin.add(flagIndiceTmp);
			return true;
		}
		return false;
	}

	/**
	 * rmvFlagIndicesDebut : Retire un indice à activer à une heure indiquée dans la liste de flagIndicesDebut
	 * @param pIndice : Indice à supprimer
	 * @param pHeure : Heure de l'indice à supprimer
	 * @return
	 * 		- false si le flag n'existait pas dans la liste flagIndicesDebut.
	 * 		- true si le flag a été supprimé.
	 */
	public boolean rmvFlagIndicesDebut(Indice pIndice, int pHeure)
	{
		int i=0;
		FlagIndice flagIndiceTmp = new FlagIndice(pIndice,pHeure);
		if(this.flagIndicesDebut.contains(flagIndiceTmp))
			for(FlagIndice fi : this.flagIndicesDebut)
			{
				if(fi.equals(flagIndiceTmp))
				{
					this.flagIndicesDebut.remove(i);
					return true;
				}
				i++;
			}
		return false;
	}

	/**
	 * rmvFlagIndicesFin : Retire un indice à desactiver à une heure indiquée dans la liste de flagIndicesFin
	 * @param pIndice : Indice à supprimer
	 * @param pHeure : Heure de l'indice à supprimer
	 * @return
	 * 		- false si le flag n'existait pas dans la liste flagIndicesFin.
	 * 		- true si le flag a été supprimé.
	 */
	public boolean rmvFlagIndicesFin(Indice pIndice, int pHeure)
	{
		int i=0;
		FlagIndice flagIndiceTmp = new FlagIndice(pIndice,pHeure);
		if(this.flagIndicesFin.contains(flagIndiceTmp))
			for(FlagIndice fi : this.flagIndicesFin)
			{
				if(fi.equals(flagIndiceTmp))
				{
					this.flagIndicesFin.remove(i);
					return true;
				}
				i++;
			}
		return false;
	}


	/*
	 * Getters & Setters
	 */

	/**
	 * getFlagIndicesDebut
	 * @return Retourne la liste des flags pointant sur les début de vie des indices
	 */
	public ArrayList<FlagIndice> getFlagIndicesDebut()
	{
		return this.flagIndicesDebut;
	}

	/**
	 * getFlagIndicesFin
	 * @return Retourne la liste des flags pointant sur les fin de vie des indices
	 */
	public ArrayList<FlagIndice> getFlagIndicesFin()
	{
		return this.flagIndicesFin;
	}

	private void checkIndice()
	{
		for(FlagIndice fl : this.flagIndicesDebut)
			if(fl.getHeure() == this.tempsRestant)
			{
				this.historique.addEvtIndiceOn(this.tempsRestant, ConstantesAdmin.COLOR_EVT_INDICE, fl.getIndice());
				((AdminModel)this.model).updateVue();
			}
		for(FlagIndice fl : this.flagIndicesFin)
			if(fl.getHeure() == this.tempsRestant)
			{
				this.historique.addEvtIndiceOff(this.tempsRestant, ConstantesAdmin.COLOR_EVT_INDICE, fl.getIndice());
				((AdminModel)this.model).updateVue();
			}
	}
}
